package com.zerowidth.moc.web.utils;

import com.zerowidth.moc.web.bean.PairInt;

import java.lang.reflect.Array;
import java.util.*;

public class CollectionUtil {

    public static <T> int size(List<T> list) {
        if (list == null) {
            return 0;
        }

        return list.size();
    }

    public static <T> boolean isEmpty(List<T> list) {
        if (list == null || list.isEmpty()) {
            return true;
        }
        return false;
    }

    public static <T> boolean isNotEmpty(List<T> list) {
        return !isEmpty(list);
    }


    public static <T extends Comparable> T max(List<T> list) {
        return (T) Collections.max(list);
    }

    public static <T> T first(List<T> list) {
        if (list == null || list.isEmpty()) {
            return null;
        }

        return list.get(0);
    }


    public static <T> T last(List<T> list) {
        if (list == null || list.isEmpty()) {
            return null;
        }

        return list.get(list.size() - 1);
    }

    /**
     * 查找倒数第二个，如果长度小于 2 则返回 null
     */
    public static <T> T penult(List<T> list) {
        if (list == null || list.isEmpty() || list.size() == 1) {
            return null;
        }

        return list.get(list.size() - 2);
    }

    public static int[] delete(int[] intArr, int target) {
        if (intArr == null || intArr.length == 0) {
            return null;
        }

        int count = CollectionUtil.count(intArr, target);

        if (count > 0) {
            int[] resultArr = new int[intArr.length - count];
            for (int i = 0, j = 0; i < intArr.length; i++) {
                if (intArr[i] != target) {
                    resultArr[j++] = intArr[i];
                }
            }
            return resultArr;
        }

        return intArr;
    }

    public static int[] delete(int[] intArr, int... target) {
        if (intArr == null || intArr.length == 0) {
            return null;
        }

        for (int i = 0; i < target.length; i++) {
            intArr = delete(intArr, target[i]);
        }

        return intArr;
    }

    public static <T> boolean isLast(List<T> list, int index) {
        if (list == null || list.isEmpty()) {
            return false;
        }

        if (index == list.size() - 1) {
            return true;
        }

        return false;
    }


    public static <T> int[] reverse(int[] intArr) {
        if (intArr == null) {
            return null;
        }

        int[] result = new int[intArr.length];
        for (int i = 0; i < result.length; i++) {
            result[i] = intArr[intArr.length - 1 - i];
        }

        return result;
    }

    public static <T> boolean exist(int[] intArr, int target) {
        for (int i = 0; i < intArr.length; i++) {
            if (intArr[i] == target) {
                return true;
            }
        }
        return false;
    }

    public static <T> int count(int[] intArr, int target) {
        if (intArr == null) {
            return 0;
        }

        int count = 0;
        for (int i = 0; i < intArr.length; i++) {
            if (intArr[i] == target) {
                count++;
            }
        }
        return count;
    }

    public static <T> int index(T[] arr, T t) {
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == t) {
                return i;
            }
        }
        return -1;
    }

    public static int sum(int[] arr) {
        int total = 0;
        for (int i = 0; i < arr.length; i++) {
            total += arr[i];
        }
        return total;
    }

    /**
     * 计算数据中前 endIndex 个数值的总和
     *
     * @param arr      目标数组
     * @param endIndex 终止位置，包含此位置
     */
    public static int sum(int[] arr, int endIndex) {
        int total = 0;
        for (int i = 0; i <= Math.min(endIndex, arr.length - 1); i++) {
            total += arr[i];
        }
        return total;
    }

    /**
     * 计算列表数值的总和
     *
     * @param list 目标数组
     */
    public static int sum(List<Long> list) {
        if (list == null) {
            return 0;
        }

        int total = 0;
        for (int i = 0; i < list.size(); i++) {
            total += list.get(i);
        }
        return total;
    }

    public static PairInt[] sortBig2Small(PairInt[] sourceArr) {
        List<PairInt> list = new ArrayList<>(Arrays.asList(sourceArr));

        Collections.sort(list, new Comparator<PairInt>() {
            @Override
            public int compare(PairInt o1, PairInt o2) {
                return o1.compareTo(o2);
            }
        });

        Collections.reverse(list);

        for (int i = 0; i < list.size(); i++) {
            sourceArr[i] = list.get(i);
        }

        return sourceArr;
    }

    public static PairInt[] sortSmall2Big(PairInt[] sourceArr) {
        List<PairInt> list = new ArrayList<>(Arrays.asList(sourceArr));

        Collections.sort(list, new Comparator<PairInt>() {
            @Override
            public int compare(PairInt o1, PairInt o2) {
                return o1.compareTo(o2);
            }
        });

        for (int i = 0; i < list.size(); i++) {
            sourceArr[i] = list.get(i);
        }

        return sourceArr;
    }

    public static int[] merge(int[] a, int[] b) {
        int[] result = new int[a.length + b.length];

        for (int i = 0; i < a.length; i++) {
            result[i] = a[i];
        }

        for (int i = 0; i < b.length; i++) {
            result[a.length + i] = b[i];
        }

        return result;
    }

    public static <T> T[] merge(T[] a, T[] b, T[] result) {
        for (int i = 0; i < a.length; i++) {
            result[i] = a[i];
        }

        for (int i = 0; i < b.length; i++) {
            result[a.length + i] = b[i];
        }

        return result;
    }

    public static int randomSelectByWeight(int[] weight) {
        if (weight == null) {
            return -1;
        }
        if (weight.length == 1) {
            return 0;
        }

        int totalWeight = sum(weight);
        int value = (int) (Math.random() * totalWeight);

        int temp = 0;
        for (int i = 0; i < weight.length; i++) {
            if (value < temp + weight[i]) {
                return i;
            } else {
                temp += weight[i];
            }
        }

        return -1;
    }

    /**
     * 将数组按从大到小的规则重新排序
     */
    public static int[] sortBig2Small(int[] intArr) {
        List<Integer> list = new ArrayList<>(intArr.length);
        for (int i = 0; i < list.size(); i++) {
            list.add(intArr[i]);
        }

        Collections.sort(list);
        Collections.reverse(list);

        for (int i = 0; i < list.size(); i++) {
            intArr[i] = list.get(i);
        }

        return intArr;
    }

    /**
     * 将数组按从小到到的规则重新排序
     */
    public static int[] sortSmall2Big(int[] intArr) {
        List<Integer> list = new ArrayList<>(intArr.length);
        for (int i = 0; i < list.size(); i++) {
            list.add(intArr[i]);
        }

        Collections.sort(list);

        for (int i = 0; i < list.size(); i++) {
            intArr[i] = list.get(i);
        }

        return intArr;
    }

    /**
     * 计算列表数值的总和的平均值
     *
     * @param list 目标数组
     */
    public static long average(List<Long> list) {
        if (isEmpty(list)) {
            return 0;
        }
        return sum(list) / list.size();
    }

    /**
     * 计算数据中前 endIndex 个数值的总和
     *
     * @param list     目标数组
     * @param endIndex 终止位置，包含此位置
     */
    public static int sum(List<Long> list, int endIndex) {
        if (list == null) {
            return 0;
        }

        int total = 0;
        for (int i = 0; i <= Math.min(endIndex, list.size() - 1); i++) {
            total += list.get(i);
        }
        return total;
    }

    /**
     * 计算数据中前 endIndex 个数值的总和
     *
     * @param list     目标数组
     * @param endIndex 终止位置，不包含此位置
     */
    public static int sum2(List<Long> list, int endIndex) {
        if (list == null) {
            return 0;
        }

        int total = 0;
        for (int i = 0; i < Math.min(endIndex, list.size()); i++) {
            total += list.get(i);
        }
        return total;
    }

    public static List<Integer> copy(List<Integer> integerList) {
        if (isEmpty(integerList)) {
            return null;
        }
        List<Integer> resultList = new ArrayList<>();

        resultList.addAll(integerList);

        return resultList;
    }

    public static void copy(int[] from, int[] to) {
        if (from.length != to.length) {
            throw new IllegalArgumentException("入参数组长度不一致，无法保证复制操作的安全性");
        }

        for (int i = 0; i < from.length; i++) {
            to[i] = from[i];
        }
    }

    public static <T> T next(List<T> list, int index) {

        if (index < 0 || list == null || index >= list.size()) {
            return null;
        }

        if (index < list.size() - 1) {
            return list.get(index + 1);
        }

        return list.get(0);
    }

    public static int indexOf(int[] arr, int target) {
        if (arr == null || arr.length == 0) {
            return -1;
        }

        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == target) {
                return i;
            }
        }

        return -1;
    }

    public static String toString(int[] intArr) {
        if (intArr == null || intArr.length == 0) {
            return "";
        }

        String result = "";
        String tail = ", ";

        for (int i = 0; i < intArr.length; i++) {
            result += intArr[i] + tail;
        }
        if (result.length() > 0) {
            result = result.substring(0, result.length() - tail.length());
        }

        return result;
    }

    public static String toString(String[] stringArr) {
        if (stringArr == null || stringArr.length == 0) {
            return "";
        }

        String result = "";
        String tail = ", ";

        for (int i = 0; i < stringArr.length; i++) {
            result += stringArr[i] + tail;
        }
        if (result.length() > 0) {
            result = result.substring(0, result.length() - tail.length());
        }

        return result;
    }

    public static String toString(Object[] stringArr) {
        if (stringArr == null || stringArr.length == 0) {
            return "";
        }

        String result = "";
        String tail = ", ";

        for (int i = 0; i < stringArr.length; i++) {
            result += stringArr[i] + tail;
        }
        if (result.length() > 0) {
            result = result.substring(0, result.length() - tail.length());
        }

        return result;
    }

    public static String toString(double[] doubleArr) {
        if (doubleArr == null || doubleArr.length == 0) {
            return "";
        }

        String result = "";
        String tail = ", ";

        for (int i = 0; i < doubleArr.length; i++) {
            result += doubleArr[i] + tail;
        }
        if (result.length() > 0) {
            result = result.substring(0, result.length() - tail.length());
        }

        return result;
    }

    public static <T> String toString(List<T> list) {
        if (list == null || list.isEmpty()) {
            return "";
        }

        String result = "";
        String tail = ", ";

        for (int i = 0; i < list.size(); i++) {
            result += list.get(i) + tail;
        }
        if (result.length() > 0) {
            result = result.substring(0, result.length() - tail.length());
        }

        return result;
    }

}
